using System;
using System.Collections;
using System.Runtime.InteropServices;

namespace Script_Text_Editor_WPF_Edition.Support.Backend
{
    public class BytesHelper
    {
        public static int FindByte(byte[] bytesInput, byte pattern, int intStart)
        {
            for (int i = intStart; i < bytesInput.Length; i++)
            {
                if (bytesInput[i] == pattern)
                    return i;
            }
            return -1;
        }

        public static int FindBytes(byte[] bytesInput, byte[] bytesFind, int intStart)
        {
            for (int index = intStart; index <= (bytesInput.Length - bytesFind.Length); index++)
            {
                if (IsBytesEqual(CopyBlock(bytesInput, index, bytesFind.Length), bytesFind))
                    return index;
            }
            return -1;
        }

        public static bool IsBytesEqual(byte[] byte1, byte[] byte2)
        {
            if (byte1.Length != byte2.Length)
                return false;

            for (int i = 0; i < byte1.Length; i++)
            {
                if (byte1[i] != byte2[i])
                    return false;
            }
            return true;
        }

        public static byte[] FillArray(byte[] bytesInput, byte byteValue)
        {
            byte[] bytesReturn = bytesInput;
            ArrayList.Repeat(byteValue, bytesInput.Length).CopyTo(bytesReturn);

            return bytesReturn;
        }

        public static byte[] SetBytes(byte[] bytesInput, byte[] bytesValue)
        {
            int i = 0;
            foreach (byte byteChar in bytesValue)
            {
                bytesInput[i] = byteChar;
                i++;
            }
            return bytesInput;
        }

        public static byte[] CopyBlock(byte[] bytesOrg, int intStart, int intLength)
        {
            try
            {
                byte[] byteOutput = new byte[intLength];

                for (int i = 0; i < intLength; i++)
                {
                    byteOutput[i] = bytesOrg[intStart + i];
                }
                return byteOutput;
            }
            catch (Exception e)
            {
                Console.WriteLine(string.Format("{0}{1}", e.Message, intStart));
                return null;
            }
        }

        public static object CopyStruct(object from, Type type)
        {
            byte[] bytes = StructToBytes(from);
            return BytesToStruct(bytes, type);
        }

        public static object BytesToStruct(byte[] bytes, Type strcutType)
        {
            int size = Marshal.SizeOf(strcutType);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(bytes, 0, buffer, size);
                return Marshal.PtrToStructure(buffer, strcutType);
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }

        public static byte[] StructToBytes(object structObj)
        {
            int size = Marshal.SizeOf(structObj);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structObj, buffer, true);
                byte[] bytes = new byte[size];
                Marshal.Copy(buffer, bytes, 0, size);
                return bytes;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }

        public static byte[] BitStringToBytes(string bit_str)
        {
            if (bit_str.IndexOf('-') == -1 && bit_str.Length == 2)
            {
                byte[] byteTemp2 = new byte[1];
                byteTemp2[0] = byte.Parse(bit_str, System.Globalization.NumberStyles.AllowHexSpecifier);
                return byteTemp2;
            }

            string[] arrSplit = bit_str.Split('-');
            byte[] byteTemp = new byte[arrSplit.Length];
            for (int i = 0; i < byteTemp.Length; i++)
            {
                byteTemp[i] = byte.Parse(arrSplit[i], System.Globalization.NumberStyles.AllowHexSpecifier);
            }
            return byteTemp;
        }
    }
}